package cn.drenal.capcap.service.impl;

import cn.drenal.capcap.entity.SysPermission;
import cn.drenal.capcap.entity.SysRolePermission;
import cn.drenal.capcap.entity.dto.PermissionDTO;
import cn.drenal.capcap.entity.vo.PermissionTreeVO;
import cn.drenal.capcap.exception.BizException;
import cn.drenal.capcap.mapper.SysPermissionMapper;
import cn.drenal.capcap.mapper.SysRolePermissionMapper;
import cn.drenal.capcap.service.SysPermissionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 权限服务实现类
 */
@Service
@RequiredArgsConstructor
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionService {

    private final SysRolePermissionMapper rolePermissionMapper;

    @Override
    public SysPermission createPermission(PermissionDTO permissionDTO) {
        // 检查权限编码是否已存在
        if (lambdaQuery().eq(SysPermission::getCode, permissionDTO.getCode()).exists()) {
            throw new BizException("权限编码已存在");
        }

        // 创建权限对象
        SysPermission permission = new SysPermission();
        BeanUtils.copyProperties(permissionDTO, permission);

        // 保存权限
        save(permission);
        return permission;
    }

    @Override
    public SysPermission updatePermission(Long id, PermissionDTO permissionDTO) {
        // 检查权限是否存在
        SysPermission permission = getById(id);
        if (permission == null) {
            throw new BizException("权限不存在");
        }

        // 检查权限编码是否已存在（排除自身）
        if (lambdaQuery().eq(SysPermission::getCode, permissionDTO.getCode()).ne(SysPermission::getId, id).exists()) {
            throw new BizException("权限编码已存在");
        }

        // 更新权限信息
        BeanUtils.copyProperties(permissionDTO, permission);
        permission.setId(id); // 确保ID不变

        // 保存更新
        updateById(permission);
        return permission;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePermission(Long id) {
        // 检查权限是否存在
        if (!lambdaQuery().eq(SysPermission::getId, id).exists()) {
            throw new BizException("权限不存在");
        }

        // 检查是否有子权限
        if (lambdaQuery().eq(SysPermission::getParentId, id).exists()) {
            throw new BizException("该权限下存在子权限，无法删除");
        }

        // 删除角色权限关联
        rolePermissionMapper.delete(new LambdaQueryWrapper<SysRolePermission>().eq(SysRolePermission::getPermissionId, id));

        // 删除权限
        removeById(id);
    }

    @Override
    public SysPermission getPermissionById(Long id) {
        SysPermission permission = getById(id);
        if (permission == null) {
            throw new BizException("权限不存在");
        }
        return permission;
    }

    @Override
    public List<SysPermission> getPermissionList() {
        return lambdaQuery()
                .orderByAsc(SysPermission::getSort)
                .orderByAsc(SysPermission::getCreateTime)
                .list();
    }

    @Override
    public List<PermissionTreeVO> getPermissionTree() {
        // 获取所有权限
        List<SysPermission> permissions = getPermissionList();
        if (permissions.isEmpty()) {
            return new ArrayList<>();
        }

        // 转换为树形结构VO
        List<PermissionTreeVO> permissionVOList = permissions.stream().map(permission -> {
            PermissionTreeVO vo = new PermissionTreeVO();
            BeanUtils.copyProperties(permission, vo);
            return vo;
        }).collect(Collectors.toList());

        // 构建权限ID与权限VO的映射关系
        Map<Long, PermissionTreeVO> permissionMap = permissionVOList.stream()
                .collect(Collectors.toMap(PermissionTreeVO::getId, permission -> permission));

        // 构建树形结构
        List<PermissionTreeVO> rootPermissions = new ArrayList<>();
        for (PermissionTreeVO permission : permissionVOList) {
            Long parentId = permission.getParentId();
            if (parentId == null) {
                // 根节点
                rootPermissions.add(permission);
            } else {
                // 子节点，添加到父节点的children列表中
                PermissionTreeVO parentPermission = permissionMap.get(parentId);
                if (parentPermission != null) {
                    if (parentPermission.getChildren() == null) {
                        parentPermission.setChildren(new ArrayList<>());
                    }
                    parentPermission.getChildren().add(permission);
                }
            }
        }

        // 对树形结构进行排序
        sortPermissionTree(rootPermissions);

        return rootPermissions;
    }

    /**
     * 递归排序权限树
     *
     * @param permissions 权限列表
     */
    private void sortPermissionTree(List<PermissionTreeVO> permissions) {
        if (permissions == null || permissions.isEmpty()) {
            return;
        }

        // 按排序字段排序
        permissions.sort(Comparator.comparing(PermissionTreeVO::getSort, Comparator.nullsLast(Comparator.naturalOrder())));

        // 递归排序子节点
        for (PermissionTreeVO permission : permissions) {
            if (permission.getChildren() != null && !permission.getChildren().isEmpty()) {
                sortPermissionTree(permission.getChildren());
            }
        }
    }
}